/* localStorage&SessionStorage */
import Vue from 'vue'
import { aes, getType } from './tools'

const THAT = Vue.prototype

class Storage {
  constructor(storage) {
    if (!storage) {
      THAT.$message.error('storage')
    }
    this._storage = storage
  }

  /**
   * @description 存值
   * @author fanzhongxu
   * @param {*} key 键
   * @param {*} val 值
   */
  setItem(key, val) {
    if (!this._storage) return
    const kType = getType(key)
    if (kType !== 'string') {
      THAT.$message.error('key只能为字符串！')
    } else {
      const cipherValue = aes.aesEncrypt(this.filterValue(val))
      this._storage.setItem(key, cipherValue)
    }
  }

  /**
   * @description 根据key获取值
   * @author fanzhongxu
   * @param {*} key 键
   * @returns 返回key对应的值
   */
  getItem(key) {
    if (!this._storage) return
    const kType = getType(key)
    let res = null
    if (kType !== 'string') {
      THAT.$message.error('key只能为字符串！')
    } else {
      res = this._storage.getItem(key)
      res = aes.aesDecrypt(res)
    }
    return res
  }

  /**
   * @description 删除key对应值
   * @author fanzhongxu
   * @param {*} key 键
   */
  removeItem(key) {
    if (!this._storage) return
    const kType = getType(key)
    if (kType !== 'string') {
      THAT.$message.error('key只能为字符串！')
    } else {
      this._storage.removeItem(key)
    }
  }

  /**
   * @description 删除所有键值
   * @author fanzhongxu
   */
  clear() {
    if (!this._storage) return
    this._storage.clear()
  }

  /**
   * @description 过滤val值
   * @author fanzhongxu
   * @param {*} val 待过滤的值
   * @returns 过滤后的值
   */
  filterValue(val) {
    const vType = getType(val)
    const nullType = ['null', 'undefined', 'NaN']
    const stringType = ['boolean', 'number', 'string']
    if (nullType.includes(vType)) return ''
    if (stringType.includes(vType)) return val.toString()
    return JSON.stringify(val)
  }
}

class LocalStorage extends Storage {
  constructor(storage) {
    super(storage)
    this.description = 'localStorage'
  }
}

class SessionStorage extends Storage {
  constructor(storage) {
    super(storage)
    this.description = 'sessionStorage'
  }
}

const lStorage = new LocalStorage(window.localStorage || localStorage)
const sStorage = new SessionStorage(window.sessionStorage || sessionStorage)

export { lStorage, sStorage }
